package com.qingge.springboot.utils;

import cn.hutool.core.lang.Assert;
import com.qingge.springboot.common.Constants;
import com.qingge.springboot.entity.dto.PhotoLimit;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.UUID;

/**
 * @author linyanbin
 * @date 2022/7/16 16:20
 */
@Service
public class PhotoUtils {

    @Autowired
    PhotoLimit photoLimit;

    /** 图片大小单位 **/
    private static final String B = "B";
    private static final String KB = "KB";
    private static final String MB = "MB";
    private static final String GB = "GB";

    private static final int NO_LIMIT = -1;
    /**
     * 限制图片的大小
     * @param len 传入图片的大小（单位：bytes）
     * @param size 图片的最大限制
     * @param unit 图片大小限制的单位
     * @return java.lang.boolean
     */
    public static boolean checkPhotoSize(Long len, Integer size, String unit) {
        if (size == NO_LIMIT) {
            return true;
        }
        double fileSize = 0;
        if (B.equalsIgnoreCase(unit)) {
            fileSize = (double) len;
        } else if (KB.equalsIgnoreCase(unit)) {
            fileSize = (double) len / 1024;
        } else if (MB.equalsIgnoreCase(unit)) {
            fileSize = (double) len / 1048576;
        } else if (GB.equalsIgnoreCase(unit)) {
            fileSize = (double) len / 1073741824;
        }
        return fileSize <= size;
    }
    /**
     * 保存图片文件，并返回保存的相对路径
     * @Param [photo]
     * @return java.lang.String
     **/
    public String savePhoto(MultipartFile photo) {
        // 判空
        if (null == photo || photo.isEmpty()) {
            // 如果文件为空，则返回空
            return null;
        }
        // 限制图片文件大小
        if (photoLimit.getPhotoMaxSize() != NO_LIMIT) {
            Assert.isTrue(checkPhotoSize(photo.getSize(), photoLimit.getPhotoMaxSize(), photoLimit.getUnit()), "图片文件过大！");
        }
        // 获取上传文件名,包含后缀
        String originalFileName = photo.getOriginalFilename();
        // 在文件名非空的情况下，从.开始获取到文件名末尾的子字符串，从而获取文件后缀
        String fileType = originalFileName != null ? originalFileName.substring(originalFileName.lastIndexOf(".") + 1) : null;
        // 用来判断是不是图片类型
        boolean isPhotoType = false;
        // 判断文件后缀是否为是图片文件后缀名中的一种，若是，则就说明上传的文件是图片文件
        for (int i = 0; i < Constants.PHOTO_SUFFIX.length; i++) {
            if (null != fileType && fileType.equalsIgnoreCase(Constants.PHOTO_SUFFIX[i])) {
                isPhotoType = true;
                break;
            }
        }
        // 如果不是图片类型，则返回空
        if (!isPhotoType) {
            return null;
        }
        // 图片保存目录
        String path = Constants.PHOTO_PATH;
        // 图片文件名，用于存储图片时需要
        String photoFileName = UUID.randomUUID() + "." + fileType;
        // 通过最后一级目录文件路径，创建File对象， 用于生成的目录文件夹
        File file = new File(path);
        // 通过图片要生成的目录文件夹的路径，以及图片文件名，创建File对象，用于生成图片
        File photoFile = new File(path, photoFileName);
        // 判断目录文件夹是否存在
        if (!file.exists()) {
            // 如果不存在，则根据该路径创建目录文件夹
            if (!file.mkdirs()) {
                // 创建文件失败，则返回空
                return null;
            }
        }
        // 图片生成路径
        String photoPath = Constants.PHOTO_SHOW_PATH + "/" + photoFileName;
        try {
            // 通过FileUtils工具类的copyInputStreamToFile方法，传入图片文件的输入流，和包含图片生成路径的File对象，来将图片输入流转换为图片文件
            FileUtils.copyInputStreamToFile(photo.getInputStream(), photoFile);
        } catch (IOException e) {
            e.printStackTrace();
            // 如果生成图片文件失败，则返回空
            return null;
        }
        // 如果创建父目录文件夹、子目录文件夹，以及生成图片成功，则返回图片存储路径
        return photoPath;
    }

    /**
     * 通过路径删除图片
     * @param path 图片路径
     */
    public void deletePhotoByPath(String ... path) {
        for (String url : path) {
            if (StringUtil.isEmptyOrNull(url)) {
                return;
            }
            url = url.replace(Constants.PHOTO_SHOW_PATH, Constants.PHOTO_PATH);
            File file = new File(url);
            if (file.exists()) {
                file.delete();
            }
        }
    }
}
